import { Button } from "antd";

declare global {
  interface Window {
    app?: any;
  }
}

interface IHook {
  queue: IQueue;
  memoizedState: number;
  next: IHook | null | undefined;
}

interface IUpdate {
  action: any;
  next: IUpdate | null | undefined;
}

interface IQueue {
  pending: IUpdate | null | undefined;
}

let workInProgressHook: any;
let isMount = true; // 是mount还是update

const fiber: any = {
  memoizedState: null, //保存该FunctionComponent对应的hooks链表
  stateNode: null,
};

const schedule = () => {
  /**
   * 更新前将workInProgressHook重置为fiber保存的第一个hook
   * workInProgressHook指向当前正在工作的hook
   * 在组件render时，每当遇到下一个useState，移动workInProgressHook的指针
   *
   */
  console.log("schedule");

  workInProgressHook = fiber.memoizedState;

  //  触发组件render
  const app = fiber.stateNode();
  //  首次render为mount 后续为update
  isMount = false;
  return app;
};

const dispatchAction = (queue: IQueue, action: any) => {
  console.log("进入dispatchAction");

  //   创建update
  const update: IUpdate = {
    action,
    next: null,
  };

  // 环状单向链表操作
  if (!queue.pending) {
    update.next = update;
  } else {
    update.next = queue.pending.next;
    queue.pending.next = update;
  }

  queue.pending = update;

  console.log("进入dispatchAction中的workInProgressHook", workInProgressHook);

  // 模拟React开始调度更新
  schedule();
};

const useState = (initialState: number): [number, any] => {
  console.log("进入useState方法");

  let hook: IHook; // 当前useState使用的hook会被赋予该变量

  if (isMount) {
    // 保存update的queue
    hook = {
      queue: {
        pending: null, // 始终指向最后一个插入的update，是一个环状单向链表
      },
      // 保存hook对应的state
      memoizedState: initialState,
      // 于下一个hook链接
      next: null,
    };
    console.log("mount阶段，保存的hook", hook);
    // 将hook插入fiber.memoizedState链表末尾
    if (!fiber.memoizedState) {
      fiber.memoizedState = hook;
    } else {
      workInProgressHook.next = hook;
    }
    workInProgressHook = hook; // 移动workInProgressHook的指针
  } else {
    // update时从workInProgressHook中取出该useState对应的hook
    hook = workInProgressHook;
    workInProgressHook = workInProgressHook.next;
    console.log("update阶段，保存的hook", hook);
  }

  let baseState = hook.memoizedState; // update执行前的初始state
  if (hook.queue.pending) {
    // 根据Queue pending中保存的update更新state
    let firstUpdate = hook.queue.pending.next; // 获取环状单向链表中第一个update
    do {
      const action = firstUpdate?.action;
      baseState = action(baseState);
      firstUpdate = firstUpdate?.next;
      console.log(
        firstUpdate,
        hook.queue.pending,
        firstUpdate !== hook.queue.pending
      );
    } while (firstUpdate !== hook.queue.pending);
    hook.memoizedState = baseState;
  }
  return [baseState, dispatchAction.bind(null, hook.queue)];
};

const App = () => {
  const [num, updateNum] = useState(0);

  console.log(`${isMount ? "mount" : "update"} num: `, num);

  return (
    <Button onClick={() => updateNum((num: any) => num + 1)}>Add Num</Button>
  );
};

fiber.stateNode = App;

const SimpleHook = () => {
  return (
    <>
      <div>观察console log输出</div>
      {schedule()}
    </>
  );
};

export default SimpleHook;
